const express = require('express');
const fs = require("fs");
const bodyParser = require('body-parser');
const path = require("path");
const {v4: uuidv4} = require('uuid');
const basicAuth = require('express-basic-auth');
const {MongoClient} = require('mongodb')
const server = express();
const publicSrv = express();
server.set('view engine', 'ejs')
server.use(bodyParser.urlencoded({extended: false}))
server.use(bodyParser.json())

/**
 * 启用 basic 验证
 */
server.use(basicAuth({
  authorizer: (username, password) => {
    return username === 'term' && password === 'term.123'
  },
  challenge: true
}))
server.use(express.static(path.join(__dirname, 'assets')));
server.get('/term', (req, res) => {
  res.render('admin', {})
});
const DATA_CACHE = {
  data: [],
  ifModify: false
}
server.post('/data', (req, res) => {
  const requestData = req.body;
  let words = requestData.words
  let cur = requestData.cur
  let size = requestData.size
  read().then(data => {
    setNoModify(data)
    res.send(filterData(words, data, cur, size))
  })

})
publicSrv.get('/fullData', (req, res) => {
  read().then(data => {
    setNoModify(data)
    res.send(data)
  })
})

function filterData(words, list, cur, size) {
  let result = list.filter(it => it.desc.includes(words)
    || it.en_short?.toLowerCase()?.includes(words.toLowerCase())
    || it.en_full?.toLowerCase()?.includes(words.toLowerCase())
    || it.cn_short.includes(words)
    || it.cn_full.includes(words));
  let offset = size * (cur - 1)
  return {
    data: result
      .sort((a, b) => a.en_short.toLowerCase() > b.en_short.toLowerCase() ? 0 : -1)
      .slice(offset, size * cur),
    paged: {
      total: result.length,
      cur: cur,
      size: size
    }
  }
}

function setModify() {
  DATA_CACHE.ifModify = true
}

function setNoModify(data) {
  DATA_CACHE.data = data
  DATA_CACHE.ifModify = true
}

console.log('3333333333333333', process.env.NODE_ENV)

function write(data) {
  fs.writeFile('./data/term.json', JSON.stringify(data, null, 2), (err) => {
    !err && setModify()
    console.log(err)
  })
}

function read() {
  return new Promise(((resolve, reject) => {
    if (DATA_CACHE.ifModify) {
      resolve(DATA_CACHE.data)
    } else {
      fs.readFile('./data/term.json', (err, buffer) => {
        if (!err) {
          try {
            let parse = JSON.parse(buffer.toString('utf-8'));
            resolve(parse)
          } catch (e) {
            reject(e)
          }
        } else {
          reject(err)
        }
      })
    }
  }))
}

server.post('/genIds', (req, res) => {
  read().then(parse => {
    let flag = false;
    parse.forEach(it => {
      if (!it.id) {
        flag = true;
        it.id = uuidv4()
      }
    })
    flag && write(parse)
    res.send(true)
  })
})
server.post('/del', (req, res) => {
  const requestData = req.body;
  let id = requestData.id
  read().then(parse => {
    let target = parse.map(it => it.id).indexOf(id);
    console.log(target, id)
    let flag = target > -1;
    if (flag) {
      parse.splice(target, 1)
    }
    flag && write(parse)
    res.send(true)
  })
})
server.post('/add', (req, res) => {
  let newOne = req.body;
  newOne.en_short && read().then(parse => {
    let target = parse.map(it => it.en_short).indexOf(newOne.en_short);
    let flag = target > -1;
    if (flag) {
      res.send('exists')
    } else {
      newOne.id = uuidv4()
      parse.push(newOne)
      write(parse.sort((a, b) => a.en_short.toLowerCase() > b.en_short.toLowerCase() ? 0 : -1))
    }
    res.send(true)
  })
})
server.post('/edit', (req, res) => {
  let editOne = req.body;
  editOne.en_short && read().then(parse => {
    let target = parse.map(it => it.id).indexOf(editOne.id);
    let flag = target > -1;
    if (flag) {
      parse[target] = editOne
      write(parse)
    }
    res.send(true)
  })
})

server.listen(process.env.PRIVATE_PORT || 8000)
publicSrv.listen(process.env.PUBLIC_PORT || 8001)
